package com.edu.hre.struts.action.dashboard;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.bsf.util.Bean;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.util.LabelValueBean;

import com.edu.hre.common.entity.BeanChart;
import com.edu.hre.common.entity.BeanChart2;
import com.edu.hre.common.utils.BeanFinder;
import com.edu.hre.common.utils.CommonUtils;
import com.edu.hre.db.pojo.HreLeaveRequest;
import com.edu.hre.db.pojo.HreLeaveType;
import com.edu.hre.db.service.BaseService;
import com.edu.hre.db.utils.Compare;
import com.edu.hre.struts.action.leave.LeaveApproveListAction;
import com.edu.hre.struts.action.leave.LeaveRequestUpdateAction;
import com.edu.hre.struts.form.dashboard.DashLeaveForm;
import com.edu.hre.struts.form.leave.LeaveApproveListForm;

import edu.emory.mathcs.backport.java.util.Collections;

public class DashLeaveAction extends DispatchAction {
	
	private static final DecimalFormat df = new DecimalFormat("0.0");
	private static final Logger logger = Logger.getLogger(DashLeaveAction.class);
	private static final BaseService baseService = BeanFinder.getBean(BaseService.BEAN_NAME, BaseService.class);
	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
	
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		CommonUtils.println(CommonUtils.getSourceCodeLocation()); 
		DashLeaveForm beanForm = (DashLeaveForm) form;
		executeStatic(request, beanForm.getFromDate(), beanForm.getToDate());
		return mapping.findForward("dashLeave");
	}
	
	public static void executeStatic(HttpServletRequest request, Date fromDate, Date toDate) throws ParseException{
		
		List<String> listColsName = new ArrayList<String>();
		List<Integer> listCompares = new ArrayList<Integer>();
		List<Object> listValues = new ArrayList<Object>();
		
		if(fromDate != null){
			listColsName.add("firstLeave");
			listCompares.add(Compare.GREATER_EQUAL);
			listValues.add(fromDate);
		}
		if(toDate != null){
			listColsName.add("lastLeave");
			listCompares.add(Compare.LESS_EQUAL);
			listValues.add(toDate);
		}
		String colsName[] = new String[listColsName.size()];
		for(int i = 0; i < listColsName.size(); i++){
			colsName[i] = listColsName.get(i);
		}
		int[] compares = new int[listCompares.size()];
		for(int i = 0; i < listCompares.size(); i++){
			compares[i] = listCompares.get(i);
		}
		Object[] colsValue = new Object[listValues.size()];
		for(int i = 0; i < listValues.size(); i++){
			colsValue[i] = listValues.get(i);
		}
		
		String pie_partsName = "";
		String pie_partsNumber = "";
		
		int check = -1;
		Float pie_totalLeavedDays = 0f;
		List<HreLeaveType> listLeaveType = baseService.getPojos(null, -1, null, null, null, 0, 0, HreLeaveType.class);
		List<HreLeaveRequest> pie_listObjs = baseService.getPojosAnd(colsName, compares, colsValue, new String[]{"leaveTypeId"}, new Boolean[]{true}, 0, 0, HreLeaveRequest.class);
		List<BeanChart> pie_listBeanCharts =  new ArrayList<BeanChart>();
		for(int i = 0; pie_listObjs != null && i < pie_listObjs.size(); i++){
			HreLeaveRequest tmp = pie_listObjs.get(i);
			if(check != tmp.getLeaveTypeId()){
				check = tmp.getLeaveTypeId();
				pie_partsName += ";" + getNameLeaveType(listLeaveType, tmp.getLeaveTypeId());
			}
			Float leavedDays = tmp.getTotalLeaved();
			if(leavedDays == null){
				leavedDays = LeaveRequestUpdateAction.computeLeaveDays(tmp.getFirstLeave(), tmp.getLastLeave());
			}
			pie_totalLeavedDays += leavedDays;
			BeanChart beanChart = new BeanChart(tmp.getLeaveTypeId(), leavedDays);
			int index = pie_listBeanCharts.indexOf(beanChart);
			if(index < 0){
				pie_listBeanCharts.add(beanChart);
			} else {
				BeanChart holdedObj = pie_listBeanCharts.get(index);
				holdedObj.setValue(holdedObj.getValue() + beanChart.getValue());
			}
		}
		
		for(int i = 0; pie_listBeanCharts != null && i < pie_listBeanCharts.size(); i++){
			BeanChart holdedObj = pie_listBeanCharts.get(i);
			pie_partsNumber += ";" + df.format(holdedObj.getValue());
		}
		pie_partsName = pie_partsName.replaceFirst(";", "");
		pie_partsNumber = pie_partsNumber.replaceFirst(";", "");
		request.setAttribute("pie_topic", "Leaves by Type");
		request.setAttribute("pie_partsName", pie_partsName);
		request.setAttribute("pie_partsNumber", pie_partsNumber);
		request.setAttribute("pie_totalLeaveDays", pie_totalLeavedDays);
		
		CommonUtils.println("pie_partsName: " + pie_partsName);
		CommonUtils.println("pie_partsNumber: " + pie_partsNumber);
		CommonUtils.println("pie_totalLeaveDays: " + pie_totalLeavedDays);
		// ================================= end of pie chart ==================================
		
		
		Date yearStart = dateFormat.parse("01-01-" + (new Date().getYear() + 1900));
		Date yearEnd = dateFormat.parse("01-01-" + (new Date().getYear() + 1900 + 1));
		List<HreLeaveRequest> bar_listObjs = baseService.getPojosAnd(
				new String[]{"firstLeave", "lastLeave"}, 
				new int[]{Compare.GREATER_EQUAL, Compare.LESS}, 
				new Object[]{yearStart, yearEnd}, 
				new String[]{"firstLeave"}, new Boolean[]{false}, 0, 0, HreLeaveRequest.class);
		
		List<BeanChart> bar_listBeanCharts =  new ArrayList<BeanChart>();
		Float bar_totalLeaveDays = 0f;
		for(int i = 0 ; i < 12; i ++){
			BeanChart bean = new BeanChart(i, 0f);
			bar_listBeanCharts.add(bean);
			for(int k = 0; bar_listObjs != null && k < bar_listObjs.size(); k ++){
				HreLeaveRequest tmp = bar_listObjs.get(k);
				if(tmp.getFirstLeave().getMonth() == i){
					Float totalLeaved = tmp.getTotalLeaved();
					if(totalLeaved == null){
						totalLeaved = LeaveRequestUpdateAction.computeLeaveDays(tmp.getFirstLeave(), tmp.getLastLeave());
					}
					BeanChart holdedBean = bar_listBeanCharts.get(bar_listBeanCharts.indexOf(bean));
					holdedBean.setValue(holdedBean.getValue() + totalLeaved);
					bar_totalLeaveDays += totalLeaved;
				}
			}
		}
		Collections.sort(bar_listBeanCharts);
		String bar_partsNumber = "";
		for(int i = 0; bar_listBeanCharts != null && i < bar_listBeanCharts.size(); i++){
			BeanChart holdedObj = bar_listBeanCharts.get(i);
			bar_partsNumber += ";" + df.format(holdedObj.getValue());
		}
		bar_partsNumber = bar_partsNumber.replaceFirst(";", "");
		request.setAttribute("bar_partsNumber", bar_partsNumber);
		request.setAttribute("bar_partsName", "Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec");
		request.setAttribute("bar_topic", "Leaves by Month");
		CommonUtils.println("bar_partsNumber: " + bar_partsNumber);
		
		//==============================================================================================
		String bar2_partsNumber = "";
		String bar2_partsName = "";
		List<BeanChart2> listBean2 = getListBean(fromDate, toDate);
		for(int i = 0; listBean2 != null && i < listBean2.size(); i++){
			BeanChart2 bean = listBean2.get(i);
			bar2_partsName += ";" + (bean.getId() == null ? "Unknown" : bean.getId());
			bar2_partsNumber += ";" + bean.getValue();
		}
		bar2_partsName = bar2_partsName.replaceFirst(";", "");
		bar2_partsNumber = bar2_partsNumber.replaceFirst(";", "");
		request.setAttribute("bar2_partsName", bar2_partsName);
		request.setAttribute("bar2_partsNumber", bar2_partsNumber);
		request.setAttribute("bar2_topic", "Leaves by Department");
		CommonUtils.println("bar2_partsName: " + bar2_partsName);
		CommonUtils.println("bar2_partsNumber: " + bar2_partsNumber); 
	}
	
	private static String getNameLeaveType(List <HreLeaveType> listObjs, int id){
		for(int i = 0; listObjs != null && i < listObjs.size(); i++){
			HreLeaveType tmp = listObjs.get(i);
			if(id == tmp.getId()){
				return tmp.getName();
			}
		}
		return null;
	}
	
	
	private static final SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
	private static List<BeanChart2> getListBean(Date from, Date to) throws ParseException{
		String sql = 
				"select lr.emp_num, lr.first_leave, lr.last_leave, lr.total_leaved, s.name " + 
				"from hre_leave_request lr  " + 
				"inner join hre_employee e  " + 
				"on e.emp_number = lr.emp_num " + 
				"left join hre_subunit s " + 
				"on s.id = e.work_station " +
				"where e.is_deleted = false ";
		String str1 = null;
		String str2 = null;
		if(from != null){
			str1 = "lr.first_leave >= '" + dateFormat2.format(from) + "'";
		}
		if(to != null){
			str2 = "lr.last_leave <= '" + dateFormat2.format(to) + "'";
		}
		if(str1 != null){
			sql += " and " + str1;
		}
		if(str2 != null){
			sql += " and " + str2;
		}
		List<BeanChart2> listTmp = new ArrayList<BeanChart2>();
		List<Object[]> listResult = baseService.listArrayObject(sql, 0, 0);
		for(int i = 0; listResult != null && i < listResult.size(); i++){
			Object[] objs = listResult.get(i);
			String label = (String) objs[5];
			Float totalLeaved = (Float) objs[4];
			if(totalLeaved == null){
				Date firstLeave = (Date) objs[2];
				Date lastLeave = (Date) objs[3];
				totalLeaved = LeaveRequestUpdateAction.computeLeaveDays(firstLeave, lastLeave);
			}
			BeanChart2 bean = new BeanChart2(label, totalLeaved);
			if(listTmp.contains(bean)){
				BeanChart2 holdedBean = listTmp.get(listTmp.indexOf(bean));
				holdedBean.setValue(holdedBean.getValue() + bean.getValue());
			} else {
				listTmp.add(bean);
			}
		}
		return listTmp;
	}
}

